//
// Created by wxd on 2025/7/14.
//

#include "VBO.h"
#include "../global/EngineDataProperties.h"
#include "../wrapper/log/Logger.h"
#include "../wrapper/monitor/GLDebug.hpp"
#include "../global/EngineDataProperties.h"


VBO::VBO(const std::vector<float> &data, GLenum usage) {
    m_Usage = usage;
    m_Vertices = std::make_unique<std::vector<float>>(data);
    m_VBO = 0;

    GL_CALL(glGenBuffers(1, &m_VBO))
    GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_VBO))
    GL_CALL(glBufferData(GL_ARRAY_BUFFER, fSize(m_Vertices->size()), m_Vertices->data(), m_Usage))
}

VBO::VBO(const std::vector<float> &data) {
    m_Usage = GL_STATIC_DRAW;
    m_Vertices = std::make_unique<std::vector<float>>(data);
    m_VBO = 0;

    GL_CALL(glGenBuffers(1, &m_VBO))
    GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_VBO))
    GL_CALL(glBufferData(GL_ARRAY_BUFFER, fSize(m_Vertices->size()), m_Vertices->data(), m_Usage))
}

VBO::VBO(const std::vector<float> &data, GLenum usage, int comp, int location) {
    m_Usage = usage;
    m_Vertices = std::make_unique<std::vector<float>>(data);
    m_VBO = 0;
    m_Component = comp;
    m_Location = location;

    GL_CALL(glGenBuffers(1, &m_VBO))
    GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_VBO))
    GL_CALL(glBufferData(GL_ARRAY_BUFFER, fSize(m_Vertices->size()), m_Vertices->data(), m_Usage))
}


VBO::~VBO() {
    if (m_Vertices) {
        m_Vertices->clear();
    }

    destroy();
}

void VBO::bind() const {
    GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_VBO))
}

void VBO::bindLocation(const GLuint vaoId) const {
    glBindVertexArray(vaoId);
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
    glEnableVertexAttribArray(m_Location);
    glVertexAttribPointer(m_Location, m_Component, GL_FLOAT, GL_FALSE,
        fSize(m_Component), nullptr);
}

void VBO::unbind() const {
    GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0))
}

void VBO::bindData() const {
    GL_CALL(glBufferData(GL_ARRAY_BUFFER, fSize(m_Vertices->size()), m_Vertices->data(), m_Usage))
}

GLuint VBO::getVBO() const {
    return m_VBO;
}

int VBO::getComponent() const {
    return m_Component;
}

int VBO::getLocation() const {
    return m_Location;
}

int VBO::getVerticeCount() const {
    return m_Vertices->size();
}

void VBO::destroy() {
    if (m_VBO != 0) {
        glDeleteBuffers(1, &m_VBO);
        m_VBO = 0;
    }
}





